package com.hskn.hss.module.gridbind.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.module.carTrack.vo.OrderByAlarmAndViolationCar;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.employeePunchCard.entity.EmployeePunchCard;
import com.hskn.hss.module.employeePunchCard.mapper.EmployeePunchCardMapper;
import com.hskn.hss.module.grid.entity.Grid;
import com.hskn.hss.module.grid.mapper.GridMapper;
import com.hskn.hss.module.gridbind.To.GridBindByAppVo;
import com.hskn.hss.module.gridbind.To.GridBindTo;
import com.hskn.hss.module.gridbind.entity.GridBind;
import com.hskn.hss.module.gridbind.mapper.GridBindMapper;
import com.hskn.hss.module.gridbind.service.IGridBindService;
import com.hskn.hss.module.gridbind.vo.GridBindPunchCardDetailVo;
import com.hskn.hss.module.gridbind.vo.GridBindPunchCardVo;
import com.hskn.hss.module.tlemployee.entity.TlEmployee;
import com.hskn.hss.module.tlemployee.mapper.TlEmployeeMapper;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.utils.DistanceUtils;
import com.hskn.hss.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-25
 */
@Service
public class GridBindServiceImpl extends ServiceImpl<GridBindMapper, GridBind> implements IGridBindService {

    @Resource
    GridBindMapper gridBindMapper;
    @Resource
    TlEmployeeMapper tlEmployeeMapper;
    @Resource
    GridMapper gridMapper;
    @Resource
    EmployeePunchCardMapper employeePunchCardMapper;
    @Resource
    private SysDepartMapper sysDepartMapper;

    @Override
    public void delete(GridBindTo gridBindTo) {

        QueryWrapper<GridBind> gridBindQueryWrapper = new QueryWrapper<>();
        gridBindQueryWrapper.lambda().in(GridBind::getItemId, gridBindTo.getItemIdList());
        gridBindQueryWrapper.lambda().in(GridBind::getGridId, gridBindTo.getGridIdList());
        List<GridBind> gridBindList = gridBindMapper.selectList(gridBindQueryWrapper);
        for (GridBind gridBind : gridBindList) {
            gridBindMapper.deleteById(gridBind.getId());
        }
    }

    @Override
    public List<GridBindPunchCardVo> getGridBindList(GridBindTo gridBindTo) {

        List<GridBindPunchCardVo> gridBindPunchCardVoList = new ArrayList<>();
        User user = LoginUtils.getUser();
        QueryWrapper<TlEmployee> tlEmployeeQueryWrapper = new QueryWrapper<>();
        tlEmployeeQueryWrapper.lambda().eq(TlEmployee::getBindaccount, user.getUid());
        TlEmployee tlEmployee = tlEmployeeMapper.selectOne(tlEmployeeQueryWrapper);
        if (null != tlEmployee) {
            List<Grid> gridList = gridMapper.selectList(new QueryWrapper<>());
            Map<String, Grid> gridMap = gridList.stream().collect(Collectors.groupingBy(Grid::getGridId, Collectors.collectingAndThen(toList(), grids -> grids.get(0))));


            QueryWrapper<EmployeePunchCard> employeePunchCardQueryWrapper = new QueryWrapper<>();
            employeePunchCardQueryWrapper.lambda().eq(EmployeePunchCard::getEmployeeId, tlEmployee.getId());
            employeePunchCardQueryWrapper.lambda().eq(EmployeePunchCard::getPunchCardDate, StringUtils.dateToStr(new Date(), "yyyy-MM-dd"));
            List<EmployeePunchCard> employeePunchCardList = employeePunchCardMapper.selectList(employeePunchCardQueryWrapper);
            Map<String, List<EmployeePunchCard>> employeePunchCardMap = employeePunchCardList.stream().collect(Collectors.groupingBy(EmployeePunchCard::getGridId));

            QueryWrapper<GridBind> gridBindQueryWrapper = new QueryWrapper<>();
            gridBindQueryWrapper.lambda().eq(GridBind::getItemId, tlEmployee.getId());
            List<GridBind> gridBindList = gridBindMapper.selectList(gridBindQueryWrapper);

            for (GridBind gridBind : gridBindList) {
                Grid grid = gridMap.get(gridBind.getGridId());
                GridBindPunchCardVo gridBindPunchCardVo = new GridBindPunchCardVo();
                if (null != grid) {
                    gridBindPunchCardVo.setId(grid.getGridId());
                    gridBindPunchCardVo.setLat(grid.getLat());
                    gridBindPunchCardVo.setLng(grid.getLng());
                    gridBindPunchCardVo.setRadius(grid.getRadius());
                    gridBindPunchCardVo.setLngLat(grid.getLnglat());
                    gridBindPunchCardVo.setAreaType(grid.getAreaType());
                    gridBindPunchCardVo.setStartTime(grid.getStartTime());
                    gridBindPunchCardVo.setEndTime(grid.getEndTime());
                }
                List<EmployeePunchCard> employeePunchCardList1 = employeePunchCardMap.get(gridBind.getGridId());
                if (null != employeePunchCardList1) {
                    Map<String, List<EmployeePunchCard>> employeePunchCardGroupByWorkTime = employeePunchCardList1.stream().collect(Collectors.groupingBy(EmployeePunchCard::getWorkTime));

                    for (String workTime : employeePunchCardGroupByWorkTime.keySet()) {
                        List<EmployeePunchCard> employeePunchCardList2 = employeePunchCardGroupByWorkTime.get(workTime);
                        if (null != employeePunchCardList2) {
                            for (EmployeePunchCard employeePunchCard : employeePunchCardList2) {
                                GridBindPunchCardDetailVo gridBindPunchCardDetailVo = new GridBindPunchCardDetailVo();
                                gridBindPunchCardDetailVo.setEmployeePunchCardId(employeePunchCard.getId());
                                gridBindPunchCardDetailVo.setWorkTime(employeePunchCard.getWorkTime());
                                gridBindPunchCardDetailVo.setAfterWorkTime(employeePunchCard.getAfterWorkTime());
                                gridBindPunchCardDetailVo.setLaterIn(employeePunchCard.getLaterIn());
                                gridBindPunchCardDetailVo.setNoWork(employeePunchCard.getNoWork());
                                gridBindPunchCardDetailVo.setLeaveEarly(employeePunchCard.getLeaveEarly());
                                if (null == gridBindPunchCardDetailVo.getWorkTime()) {
                                    gridBindPunchCardDetailVo.setStatus(0); //上班打卡
                                }
                                if (null != gridBindPunchCardDetailVo.getWorkTime() && null == gridBindPunchCardDetailVo.getAfterWorkTime()) {
                                    gridBindPunchCardDetailVo.setStatus(1); //下班班打卡
                                }
                                if (null != gridBindPunchCardDetailVo.getWorkTime() && null != gridBindPunchCardDetailVo.getAfterWorkTime()) {
                                    gridBindPunchCardDetailVo.setStatus(2); //下班班打卡
                                }
                                gridBindPunchCardVo.setGridBindPunchCardDetailVo(gridBindPunchCardDetailVo);
                            }
                        }
                    }
                }
                gridBindPunchCardVoList.add(gridBindPunchCardVo);
            }
        }
        ListSort(gridBindPunchCardVoList);
        return gridBindPunchCardVoList;
    }

    /**
     * 根据时间排序（其他排序如根据id排序也类似）
     *
     * @param gridBindPunchCardVoList
     */
    private static void ListSort(List<GridBindPunchCardVo> gridBindPunchCardVoList) {
        //用Collections这个工具类传list进来排序
        Collections.sort(gridBindPunchCardVoList, new Comparator<GridBindPunchCardVo>() {
            @Override
            public int compare(GridBindPunchCardVo o1, GridBindPunchCardVo o2) {
                String dt1 = null;
                String dt2 = null;
                try {
                    dt1 = o1.getStartTime();
                    dt2 = o2.getStartTime();

                } catch (Exception e) {
                    e.printStackTrace();
                }
                return dt1.compareTo(dt2);
            }
        });
    }


    @Override
    public List<String> getIsInGrid(GridBindByAppVo gridBindByAppVo) {
        List<String> gridNameList = new ArrayList<>();
        Grid grid = gridMapper.selectById(gridBindByAppVo.getId());
        if (null != grid) {
            boolean isInGrid = DistanceUtils.insideGrid(Double.parseDouble(gridBindByAppVo.getLng()), Double.parseDouble(gridBindByAppVo.getLat()), grid);
            if (isInGrid) {
                gridNameList.add(grid.getName());
            }
        }
        return gridNameList;
    }

    public void punchCard(GridBindByAppVo gridBindByAppVo) {
        QueryWrapper<TlEmployee> tlEmployeeQueryWrapper = new QueryWrapper<>();
        User user = LoginUtils.getUser();
        tlEmployeeQueryWrapper.lambda().eq(TlEmployee::getBindaccount, user.getUid());
        TlEmployee tlEmployee = tlEmployeeMapper.selectOne(tlEmployeeQueryWrapper);
        if (null != tlEmployee) {
            List<SysDepart> sysDepartList = sysDepartMapper.selectList(new QueryWrapper<>());
            Map<String, SysDepart> sysDepartMap = sysDepartList.stream().collect(Collectors.groupingBy(SysDepart::getId, Collectors.collectingAndThen(toList(), values -> values.get(0))));

            Grid grid = gridMapper.selectById(gridBindByAppVo.getId());

            if (null != grid) {
                if (null == gridBindByAppVo.getEmployeePunchCardId() || "".equals(gridBindByAppVo.getEmployeePunchCardId())) {
                    EmployeePunchCard employeePunchCard = new EmployeePunchCard();
                    employeePunchCard.setPunchCardDate(DateUtil.formatDate(new Date()));
                    employeePunchCard.setPunchCardMonth(DateUtil.format(new Date(), "yyyy-MM"));
                    employeePunchCard.setEmployeeId(tlEmployee.getId());
                    employeePunchCard.setGridId(grid.getGridId());
                    employeePunchCard.setEmployeeName(tlEmployee.getName());
                    employeePunchCard.setDepartmentId(tlEmployee.getEmpldeptid());
                    SysDepart sysDepart = sysDepartMap.get(tlEmployee.getEmpldeptid());
                    if (null != sysDepart) {
                        employeePunchCard.setDepartmentName(sysDepart.getDepartName());
                    }
                    employeePunchCard.setWorkTime(DateUtil.formatTime(new Date()));
                    Long leaveEarlyTime = DateUtil.parse(employeePunchCard.getWorkTime()).getTime() + Long.parseLong(grid.getStartWorkPunchCard().toString()) - Long.parseLong(grid.getLeaveEarly().toString());
                    if (leaveEarlyTime <= DateUtil.parse(grid.getStartTime()).getTime()) {
                        employeePunchCard.setLaterIn(0);
                    } else {
                        employeePunchCard.setLaterIn(1);
                    }
                    if (null == employeePunchCard.getWorkTime()) {
                        employeePunchCard.setLackCard(1);
                    }
                    employeePunchCardMapper.insert(employeePunchCard);
                } else {
                    EmployeePunchCard employeePunchCard = employeePunchCardMapper.selectById(gridBindByAppVo.getEmployeePunchCardId());
                    employeePunchCard.setActualAfterWorkTime(DateUtil.formatTime(new Date()));

                    Long leaveEarly = DateUtil.parse(employeePunchCard.getAfterWorkTime()).getTime() - Long.parseLong(grid.getLeaveEarly().toString());
                    if (leaveEarly >= DateUtil.parse(employeePunchCard.getAfterWorkTime()).getTime()) {
                        employeePunchCard.setLeaveEarly(0);
                    } else {
                        employeePunchCard.setLeaveEarly(1);
                    }
                    //应工作时间
                    long shouldTimeDifference = DateUtil.parse(grid.getStartTime()).getTime() - DateUtil.parse(grid.getEndTime()).getTime();
                    //已经工作时间 + 超过旷工时间
                    long timeDifference = DateUtil.parse(employeePunchCard.getAfterWorkTime()).getTime() - DateUtil.parse(employeePunchCard.getWorkTime()).getTime() + Long.parseLong(grid.getNoWork().toString());

                    if (timeDifference >= shouldTimeDifference) {
                        employeePunchCard.setNoWork(0);//正常
                    } else {
                        employeePunchCard.setNoWork(1);//旷工
                    }
                    employeePunchCardMapper.updateById(employeePunchCard);
                }
            }
        }

    }
}
